#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <getopt.h>

#include "huffman.h"
#include "bmp.h"
#include "difference.h"
#include "debug.h"
#include "load.h"
#include "save.h"

extern char **code, buf[BYTES];
extern NODE *q;

#ifndef TESTE
#define PROGRAM_FINAL
#endif

int main(int argc,char **argv) {

#ifdef PROGRAM_FINAL
	
	char inputFile[BYTES],outputFile[BYTES];
	unsigned char isCompress = 0;
	int c, cOrd = 0;
	
	if( argc < 2 ){
		 printf("Bad usage of program\n");
		 printf("./compress {-c [compress] or -d [decompress]} -i [inputFile] -o [outputFile]\n");
         return 0;
	}

	while ((c = getopt (argc, argv, "hcdi:o:")) != -1){
		switch (c) {
           case 'c':
           	 if( !cOrd ){ 	
             	isCompress = 1;
             	cOrd++;
             }
             else{
             	printf("Only use -c or -d not both!!!!\n");
             }
             break;
           case 'd':
        	 if( !cOrd ){ 	
             	isCompress = 0;
             	cOrd++;
             }
             else{
             	printf("Only use -c or -d not both!!!!\n");
             }
             break;
           case 'i':
             strcpy(inputFile,optarg);
             break;
   	       case 'o':
             strcpy(outputFile,optarg);
             break;
           case 'h':
		     printf("./compress {-c [compress] or -d [decompress]} -i [inputFile] -o [outputFile]\n");
             return 1;
           default:
             abort();
       }
	}
#ifdef DEBUG
	printf("Your parameters are: \n");
	printf("%s, ",(isCompress?"Compress":"Decompress"));
	printf("-inputFile: %s, -outputFile: %s\n",inputFile,outputFile);
#endif
	BMP bmp;

	FILE *arq = fopen(inputFile,"rb");
	if(!arq){
		printf("File %s doesn't exist\n",inputFile);
		return -1;
	}

	FILE *out = fopen(outputFile,"wb");

	if( isCompress){		
    	readHeaderBMPFile(&bmp,arq);
    	readImageBMP(&bmp,arq);
    	
    	algorithmCompressor(bmp,out);
    	
		fseek(out, 0L, SEEK_END);
		int compress = ftell(out);		
		printf("Original File's size: %d\n", bmp.bmpHeader.BiSizeImag);
		printf("Compress File's size: %d\n", compress);	
		printf("Rate of Compression:  %3.2f%%\n",(float) compress*100/bmp.bmpHeader.BiSizeImag);

		free(bmp.image);	
	}
	else{	
		algorithmUncompressor(arq,out);
	}
	
	fclose(arq);
   	fclose(out);

	return 0;
#else

#ifdef TESTE

	FILE *arq, *out;

    arq = fopen("teste.bmp","rb");
    BMP bmp;
    readHeaderBMPFile(&bmp,arq);
    readImageBMP(&bmp,arq);

    out = fopen("compress.bmp","wb");
    algorithmCompressor(bmp,out);

    free(bmp.image);
    bmp.image = NULL;
    fclose(arq);
    fclose(out);

#else
    FILE *out;
    out = fopen("compress.bmp","rb");

    int size = 10000;
    unsigned char jaca[size];

    int x = fread(jaca,sizeof(unsigned char),size,out);
    while( x < size)
        x += fread(jaca+x,sizeof(unsigned char),size,out);

    int p = 0;
    while( p < 2364){
        printf("%x\n",jaca[p]);
        p++;
    }

    fclose(out);
    return 0;
#ifdef HUFFMAN_SHORT

    int i;
    short str[]={1,1,1,1,1,1,1,1,1,5,5,4,3,2,2,0};

	int max = initShortHuffmanTree(str,sizeof(str)/sizeof(short));
    for (i = 0; i < max; i++)
        if(code[i])
            printf("%d: %s\n", i, code[i]);
#else
    int i;
	char *str = "11115543", buf[1024]; 	//given text to be encoded
	init(str); //create the huffman tree

	printf("The Huffman tree is created.\n");
	for (i = 0; i < 128; i++)
		if (code[i]) printf("'%c': %s\n", i, code[i]); //display the huffman tree

	encode(str, buf);
	printf("\nEncoded text: %s\n", buf);
	printf("\n");
	printf("Decoded text: ");
	decode(buf, q[1]);

#endif
    printf("\n");
	FILE *arq;

    arq = fopen("teste.bmp","rb");
    BMP bmp;
    readHeaderBMPFile(&bmp,arq);
    printBMPFileHeader(&bmp);
    readImageBMP(&bmp,arq);

    free(bmp.image);
    bmp.image = NULL;
    fclose(arq);
#endif
#endif
	return 0;
}
